#!/usr/bin/env python3
#: Title        : iphone_sms
#: Author       : "John Lehr" <slo.sleuth@gmail.com>
#: Date         : 05/04/2011
#: Version      : 1.0.2
#: Description  : Dump/interpret iphone sms.db messages table 
#: Options      : None

#: 03/22/2011   : v1.0.0 Initial Release
#: 04/12/2011   : v1.0.1 updated flags translations
#: 05/04/2011   : v1.0.2 added extended output formats, updated code schema
#: 10/05/2011   : v2.0.0 converted to python from bash


import sqlite3, argparse
from time import strftime, localtime, gmtime

sms_flags = {
    2 : 'Recd SMS',
    3 : 'Sent SMS/MMS',
    4 : 'Recd MMS',
    33 : 'Unsent' ,
    35 : 'Failed Send',
    129 : 'Deleted'}
read_flags = {
    0 : 'Unread',
    1: 'Read' }

def printdb(args):
    '''Prints the rows from the iPhone sms.db, interpreting the flags.'''
    
    if not args.noheader:
        print('File: "{}"'.format(args.database))
        print('Record #,Date,Type,Phone Number,AdressBook ID,Duration')
    
    try: 
        conn = sqlite3.connect(args.database)
        c = conn.cursor()

        for ROWID, address, date, text, flags, read in c.execute(
            'select ROWID, address, date, text, flags, read from message'):

            #convert flags object to sms_flag dictionary value
            type = sms_flags.get(flags, 'Unknown')
            
            #convert read object to read_flags dictionary value
            status = read_flags.get(read, 'Unknown') 
    
            #convert timestamp to local time or utc
            if args.utc:
                time = strftime('%Y-%m-%d %H:%M:%S (UTC)', gmtime(date))
            else:
                time = strftime('%Y-%m-%d %H:%M:%S (%Z)', localtime(date))

            print('{},{},{},{},"{}",{}'.
                format(ROWID, time, type, address, text, status))

    except sqlite3.Error:
            print('SQLite Error: wrong or incompatible database')

def main():
    parser = argparse.ArgumentParser(
        description='Process iPhone SMS database.',
        epilog='Converts timestamps to local time and interprets flag values.  \
        Prints to stdout.')

    parser.add_argument('database', help='an iPhone sms.db database')
    parser.add_argument('-n', '--no-header', dest='noheader',
        action='store_true', help='do not print filename or column header')
    parser.add_argument('-u', '--utc', dest='utc', action='store_true',
        help='Show UTC time instead of local')
    parser.add_argument('-V', '--version', action='version',
        version='%(prog)s v2.0.0')

    args = parser.parse_args()

    printdb(args)

if __name__ == '__main__':

